package com.songlanyun.modules.payrefund.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.enums.*;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.StrUtil;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.modules.exception.OrderException;
import com.songlanyun.modules.integralrecord.entity.IntegralRecord;
import com.songlanyun.modules.integralrecord.service.IntegralRecordService;
import com.songlanyun.modules.loverecord.service.UserLoveRecordService;
import com.songlanyun.modules.order.entity.ChildOrder;
import com.songlanyun.modules.rabbitmq.MqConstant;
import com.songlanyun.modules.rabbitmq.service.SendMsgService;
import com.songlanyun.modules.rights.entity.RightsChildOrder;
import com.songlanyun.modules.rights.entity.RightsOrder;
import com.songlanyun.modules.rights.service.RightsOrderService;
import com.songlanyun.modules.sysbill.service.SysBillService;
import com.songlanyun.modules.usergains.service.UserBillService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;

import com.songlanyun.modules.payrefund.dao.PayRefundOrderDao;
import com.songlanyun.modules.payrefund.entity.PayRefundOrder;
import com.songlanyun.modules.payrefund.service.PayRefundOrderService;
import org.springframework.transaction.annotation.Transactional;


@Service("payRefundOrderService")
public class PayRefundOrderServiceImpl extends ServiceImpl<PayRefundOrderDao, PayRefundOrder> implements PayRefundOrderService {


    @Autowired
    private RightsOrderService rightsOrderService;

    @Autowired
    private SysBillService sysBillService;

    @Autowired
    private IntegralRecordService integralRecordService;

    @Autowired
    private UserLoveRecordService userLoveRecordService;

    @Autowired
    private UserBillService userBillService;

    @Override
    public PayRefundOrder create(PayRefundOrder entity) {
        ValidatorUtils.validateEntity(entity);
        this.baseMapper.insert(entity);
        return entity;
    }

    @Override
    public PayRefundOrder modify(PayRefundOrder entity) {
        ValidatorUtils.validateEntity(entity);
        this.baseMapper.updateById(entity);
        return entity;
    }

    @Override
    public void remove(Long id) {

    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PayRefundOrder> page = this.page(
                new Query<PayRefundOrder>().getPage(params),
                new QueryWrapper<PayRefundOrder>()
        );

        return new PageUtils(page);
    }


    /**
     * 退款回调处理
     * @param outRefundNo
     * @param refundId
     * @param money
     * @param payMode
     * @return
     */
    @Override
    @Transactional
    public PayRefundOrder callbackHandle(String outRefundNo, String refundId, BigDecimal money, OrderConstant.PayMode payMode) {
        PayRefundOrder refundOrder = this.getByCode(outRefundNo, true);
        return callbackHandleService(refundOrder,refundId,money,payMode);
    }

    @Override
    public PayRefundOrder callbackFailHandle(String outRefundNo, String refundId, BigDecimal money, OrderConstant.PayMode payMode) {
        PayRefundOrder refundOrder = this.getByCode(outRefundNo, true);
        return callbackHandleFailService(refundOrder,refundId,money,payMode);
    }

    @Override
    public PayRefundOrder callbackHandle(PayRefundOrder refundOrder, String refundId, BigDecimal money, OrderConstant.PayMode payMode) {
       return callbackHandleService(refundOrder,refundId,money,payMode);
    }


    private PayRefundOrder callbackHandleService(PayRefundOrder refundOrder, String refundId, BigDecimal money, OrderConstant.PayMode payMode)
    {
        RightsOrder rightsOrder = rightsOrderService.loadByPayRefundOrderId(refundOrder.getId(), true);
        /**
         * 已经退款成功不要重复操作
         */
        if(RightsOrderConstant.RightsRefundStatus.SUCCESS.equals(refundOrder.getRightsRefundStatus()))
        {
            throw new RRException(OrderException.REPEAT_REFUND);
        }

        //改变退款单
        refundOrder.setThirdRefundCode(refundId);

        this.setRefundStatus(refundOrder, RightsOrderConstant.RightsRefundStatus.SUCCESS);

        //退还积分
        if(rightsOrder.getRefundPoint().compareTo(BigDecimal.ZERO)>0) {

            integralRecordService.inner(new IntegralRecord(rightsOrder.getUserId(), rightsOrder.getRefundPoint(),
                    IntegralConstant.InnerMode.POINT_ORDER_REFUND, IntegralConstant.IntegralModelType.RIGHTS_ORDER, rightsOrder.getId(),
                    String.format("维权订单[%s]退回积分:%s", rightsOrder.getOrderCode(), refundOrder.getRefundPoint())));
        }

        /**
         * 购买商品送积分
         */
        List<RightsChildOrder> rightsChildOrders = rightsOrder.loadRightsChildOrders();
        rightsChildOrders.forEach(rightsChildOrder -> {
            ChildOrder childOrder = rightsChildOrder.getChildOrder();
            if(rightsChildOrder.getRefundNum()<childOrder.getNumber())
            {
                Integer num = childOrder.getNumber()-rightsChildOrder.getRefundNum();

                BigDecimal givePoint = MathUtils.multiply(new BigDecimal(num),childOrder.getGiveBackPoint());
                if(givePoint.compareTo(BigDecimal.ZERO)>0)
                {
                    integralRecordService.inner(new IntegralRecord(childOrder.getUserId(),givePoint,
                            IntegralConstant.InnerMode.BUY_GOODS, IntegralConstant.IntegralModelType.ORDER,childOrder.getOrderId(),
                            String.format("购买商品【%s】%d %s,订单[%s]完成,赠送积分:%s",childOrder.getGoodsTitle(),num,childOrder.getUnit(),childOrder.getOrderCode(),givePoint)));
                }


//                BigDecimal consumptionValue = MathUtils.setScale(num * childOrder.getConsumptionValue().doubleValue());
//                if(consumptionValue.compareTo(BigDecimal.ZERO)>0)
//                {
//                    if(GoodsConstant.AreaFeature.GENERAL.equals(childOrder.getAreaFeature())) {
//                        userBillService.inBill(childOrder.getUserId(),
//                                String.format("购买了\" %s\"", StrUtil.truncation(childOrder.getGoodsTitle(), 10)),
//                                UserBillConstant.InnerMode.BUY_INCOME,
//                                consumptionValue,
//                                childOrder.getOrderCode(),
//                                "系统");
//                    }
//                }
            }
        });

        //平台入账
        sysBillService.saveExpenditureBill(refundOrder.getPayMode(),
                BillConstant.BillType.REFUND,money,refundOrder.getRefundCode(),refundId,"","","","","",refundOrder.getMobile());

        if(OrderConstant.OrderType.SALE_ORDER.equals(refundOrder.getOrderType()))
        {
            rightsOrderService.refundSuccessOperate(rightsOrder);
            return refundOrder;
        }

        if(OrderConstant.OrderType.SERVICE_ORDER.equals(refundOrder.getOrderType()))
        {
            return refundOrder;
        }

        return refundOrder;

    }

    private PayRefundOrder callbackHandleFailService(PayRefundOrder refundOrder, String refundId, BigDecimal money, OrderConstant.PayMode payMode)
    {
        RightsOrder rightsOrder = rightsOrderService.loadByPayRefundOrderId(refundOrder.getId(), true);
        /**
         * 已经退款成功不要重复操作
         */
        if(RightsOrderConstant.RightsRefundStatus.SUCCESS.equals(refundOrder.getRightsRefundStatus()))
        {
            throw new RRException(OrderException.REPEAT_REFUND);
        }

        //改变退款单的状态
        refundOrder.setThirdRefundCode(refundId);

        this.setRefundStatus(refundOrder, RightsOrderConstant.RightsRefundStatus.FAIL);


        rightsOrder.setRightsRefundStatus(RightsOrderConstant.RightsRefundStatus.FAIL);
        rightsOrderService.modify(rightsOrder);

        return refundOrder;

    }

    @Override
    public PayRefundOrder getByCode(String refundCode, Boolean tw) {
        PayRefundOrder one = this.getOne(new LambdaQueryWrapper<PayRefundOrder>()
                .eq(PayRefundOrder::getRefundCode, refundCode)
                .last("limit 1"));
        if(one ==null && tw)
        {
            throw new RRException(OrderException.PAY_REFUND_ORDER_NOT_EXISTS);
        }
        return one;
    }


    @Override
    public PayRefundOrder setRefundStatus(PayRefundOrder payRefundOrder, RightsOrderConstant.RightsRefundStatus status) {
        payRefundOrder.setRightsRefundStatus(status);
        this.modify(payRefundOrder);

        return payRefundOrder;
    }

}
